package com.donald.publish

import com.google.gson.Gson
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import org.json.JSONObject
import java.io.File

/**
 * QigsawBundle调用时，会传入两个参数。
 * release：正式或测试
 * dir：所有文件的路径
 * 解析所有文件，实现上传即可。
 * 具体使用参考 main 方法。
 * */
object Main {
    @JvmStatic
    fun main(args: Array<String>) {
        val json = args.toJson()
        println(json.toString())
        val release = json.optBoolean("-release", false)
        val dir = json.optString("-dir") ?: throw  IllegalArgumentException("need param: -dir")
        val folder = File(dir)
        if (folder.exists()) {
            folder.listFiles()?.forEach {
                it.uploadFile(release)
            }
            return
        } else println("DIR IS NOT EXISTS")
    }

    private fun Array<String>.toJson(): JSONObject {
        val json = JSONObject()
        for (i in 0 until size step 2) {
            json.put(get(i), get(i + 1))
        }
        return json
    }

    private val gson = Gson()
    private val httpClient = OkHttpClient()

    /**
     * @param release debug or release
     * */
    private fun File.uploadFile(release: Boolean) {
        val host = if (release) "http://www.qigsaw.com" else "http://www.qigsaw.com"//启动本地服务器时，域名映射到了本机IP
        val info = parseVersionInfo()
        val json = JSONObject(gson.toJson(info))
        json.put("file", this)
        val request = Request.Builder()
            .url("$host/admin/versioninfo/add")
            .post(json.toMultipartBody())
            .build()
        val response = httpClient.newCall(request).execute()

        if (response.isSuccessful) {
            val res = response.body!!.string()
            val vr = gson.fromJson(res, VersionResponse::class.java)
            if (vr.isOK) {
                println(gson.toJson(vr.data))
            } else {
                println(res)
            }
        } else {
            println("${response.code}:${response.message}")
        }
    }

    private fun JSONObject.toMultipartBody(): MultipartBody {
        val builder = MultipartBody.Builder()
        builder.setType(MultipartBody.FORM)
        keys().forEach { key ->
            val v = get(key)
            if (v is File) {
                val body = v.asRequestBody("application/octet-stream".toMediaType())
                val deployFileName = if (v.name.endsWith(".json")) v.name.replace(".json", ".apk") else v.name
                builder.addFormDataPart(key, deployFileName, body)
            } else if (v != null) {
                builder.addFormDataPart(key, v.toString())
            }
        }
        return builder.build()
    }

    // "{appId}-{split}-{abi}-t{type}-v{version}-{md5}"
    private fun File.parseVersionInfo(): VersionInfo {
        println(name)
        val info = VersionInfo()
        info.packageName = "^([^-]+)".toRegex().find(name)!!.groupValues[1]
        info.versionType = "-t(\\d+)-".toRegex().find(name)!!.groupValues[1].toInt()
        val version = "-v([^-]+@\\d+)-".toRegex().find(name)!!.groupValues[1].split("@")
        info.versionName = version.first()
        info.versionCode = version.last().toInt()
        info.message = "Hello"
        if (name.endsWith(".json")) {
            //组件更新链接带上MD5，方便对比是否更新，即使Base版本号未变动。
            info.md5 = "-([0-9a-z]{32})\\.".toRegex().find(name)!!.groupValues[1]
            info.packageName += "-split"
        } else {
            val type = "-t${info.versionType}-"
            val split = name.substring(info.packageName.length + 1, name.indexOf(type))
            if (split != "base") {
                info.keepFileName = true
                info.packageName += "-$split"
            }
        }
        return info
    }
}